﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using COFE.Core.Lister;
using System.IO;
using NUnit.Framework;
using COFE.Core.Utils;
using System.Text.RegularExpressions;
using COFE.IO.FSI;
using COFE.Core.Profile;
using COFE.Core;
using COFE.Core.Entry;

namespace COFE.IO.FSIEX
{
    public class FileSystemExDirectoryLister : PrimaryDirectoryListerBase<FileSystemInfoEx>
    {
        #region Constructors

        /// <summary>
        /// 
        /// </summary>
        /// <param name="rootPath">Guid root path is not supported.</param>
        public FileSystemExDirectoryLister(IFactory<IDirectoryLister> factory, string listerKey, string rootPath = null)
            : base(factory, listerKey)
        {
            Assert.IsTrue(rootPath == null || Directory.Exists(rootPath));
            if (rootPath != null) _rootPath = rootPath.TrimEnd('\\');

            if (rootPath != null)
            {
                _rootDirectory = FileSystemInfoEx.FromString(rootPath) as DirectoryInfoEx;
                Assert.IsNotNull(_rootDirectory);
            }

            //Directory Lister
            _list = (item) => { return (item as DirectoryInfoEx).EnumerateFileSystemInfos(); };
            _isDirectory = (item) => { return item is DirectoryInfoEx; };
            _getParent = (item) =>
                {
                    DirectoryInfoEx parent = item.Parent;
                    if (_rootDirectory != null && _rootDirectory.Equals(item))
                        return null;
                    return parent;
                };


            //Primar Directory Lister
            _parse = (path) =>
            {
                if (_rootPath != null)
                    path = COFEPath.Combine(_rootPath, path);

                var retVal = FileSystemInfoEx.FromString(path);
                if (retVal.Exists)
                    return retVal;
                return null;
                //TO-DO: Check if returned entries is subentry of root directory.
            };

            _getTempPath = () => { return Path.GetTempPath(); };
            _getRootDirectory = () =>
            {
                return new DirectoryInfoEx[] { _rootDirectory != null ? _rootDirectory : DirectoryInfoEx.DesktopDirectory };
            };
            _getSupportedPathPatterns = () => { return new string[] { RegexPatterns.FileSystemPattern, RegexPatterns.FileSystemGuidPattern }; };

        }

        #endregion

        #region Methods


        public override IStreamProvider CreateStreamProvider()
        {
            return new FileSystemExStreamProvider(this);
        }

        public override IDirectoryController CreateController()
        {
            return new FileSystemExDirectoryController(this);
        }

        public override IPropertyProvider CreatePropertyProvider(FileSystemInfoEx item)
        {
            return new FileSystemExPropertyProvider(ListerKey, _rootPath, item);
        }


        #endregion


        #region Data

        private string _rootPath = null;
        private DirectoryInfoEx _rootDirectory;

        #endregion

        #region Public Properties

        public string RootPath { get { return _rootPath; } }
        //public DirectoryInfoEx RootDirectory { get { return _rootDirectory; } }

        #endregion
    }
}
